package com.robertux.leaderboard.process;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

import org.apache.log4j.Logger;

import com.robertux.leaderboard.beans.entities.ExclusionCliente;
import com.robertux.leaderboard.beans.entities.ProyeccionesFarmacia;
import com.robertux.leaderboard.beans.entities.external.Sucursal;
import com.robertux.leaderboard.util.gestoresModelos.GestorEntidades;
import com.robertux.leaderboard.util.gestoresModelos.GestorEntidadesFarmacia;
import com.robertux.leaderboard.util.gestoresModelos.GestorExclusiones;
import com.robertux.leaderboard.util.gestoresModelos.GestorProyeccionesFarmacias;

public class ProyeccionesUpdater implements Runnable {
public static final String LEADERBOARDPUPD_PU = "LeaderboardUpdPU";
	
	private Logger logger;
	private DateFormat dFmt;
	private GestorEntidadesFarmacia gEntFrm;
	private GestorExclusiones gExcls;
	private GestorProyeccionesFarmacias gProyecciones;
	private EntityManager eMgr;
	private Sucursal suc;
	private Properties sqlServerConnProps;
	private int index, total;
	private Calendar calActualizacion;
	
	public ProyeccionesUpdater(Calendar calActualizacion, Properties sqlServerConnProps, Sucursal suc, int index, int total) {
		this.logger = Logger.getLogger(this.getClass());
		this.dFmt = new SimpleDateFormat("MM/yyyy");
		this.sqlServerConnProps = sqlServerConnProps;
		this.suc = suc;
		this.index = index;
		this.total = total;
		this.calActualizacion = calActualizacion;
	}

	@Override
	public void run() {
		try {
			this.eMgr = Persistence.createEntityManagerFactory(LEADERBOARDPUPD_PU).createEntityManager();
			this.gEntFrm = new GestorEntidadesFarmacia(this.sqlServerConnProps);
			this.gProyecciones = new GestorProyeccionesFarmacias(new GestorEntidades<ProyeccionesFarmacia>(this.eMgr));
			this.gExcls = new GestorExclusiones(new GestorEntidades<ExclusionCliente>(this.eMgr));
			
			this.udpateProyeccionFarmacia();
		} catch (Exception e) {
			this.logger.error("Error tratando de configurar las conexiones a las bases de datos: " + e.getMessage(), e);
		} finally {
			if(this.eMgr != null) {
				try { this.eMgr.close(); this.eMgr = null; } catch(Exception ex) { this.logger.warn("Error tratando de cerrar el EntityManager: " + ex.getMessage()); }
			}
		}
	}
	
	public void udpateProyeccionFarmacia() {
		this.logger.info("\n\n\n==== Actualizando proyección " + (this.index+1) + " de " + this.total + " para farmacia " + this.suc.getId() + " - " + this.suc.getNombre());
		double ventas = 0;
		
		ProyeccionesFarmacia proyeccion = this.gProyecciones.getProyeccion(suc.getId(), this.calActualizacion.get(Calendar.YEAR), this.calActualizacion.get(Calendar.MONTH)+1);
		List<ExclusionCliente> exclusiones = this.gExcls.getExclusiones();
		
		if(proyeccion != null) {
			try {
				ventas = this.gEntFrm.getTotalPrecioVentasSucursal(calActualizacion, this.suc, exclusiones);
				proyeccion.setVentas(new BigDecimal(ventas));
				
				if(this.gProyecciones.actualizarProyeccion(proyeccion)) {
					this.logger.info("Proyección con ID " + proyeccion.getId() + " creada o actualizada satisfactoriamente con valor de ventas " + ventas);
				} else {
					this.logger.error("No se pudo crear o actualizar proyección con ID " + proyeccion.getId());
				}
			} catch (Exception e) {
				this.logger.error("Error tratando de calcular las ventas totales para la sucursal " + suc + ": " + e.getMessage(), e);
			}
		} else {
			this.logger.error("No se ha generado una meta para la sucursal " + suc + " y el mes " + dFmt.format(calActualizacion.getTime()));
		}
		
	}

}
